package cn.gdut.chengcai.controller;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.gdut.chengcai.base.ConstantUtil;
import cn.gdut.chengcai.base.EmailUtil;
import cn.gdut.chengcai.base.JsonUtil;
import cn.gdut.chengcai.base.MemberUtil;
import cn.gdut.chengcai.base.MessageUtil;
import cn.gdut.chengcai.base.RequestUtil;
import cn.gdut.chengcai.base.ResponseData;
import cn.gdut.chengcai.entity.MemberInfo;
import cn.gdut.chengcai.entity.MemberInfoExample;
import cn.gdut.chengcai.entity.SecretKeyInfo;
import cn.gdut.chengcai.entity.SecretKeyInfoExample;
import cn.gdut.chengcai.entity.ValidateLogInfo;
import cn.gdut.chengcai.enums.EmailTemplateType;
import cn.gdut.chengcai.service.EmailLogInfoService;
import cn.gdut.chengcai.service.EmailTemplateInfoService;
import cn.gdut.chengcai.service.KeyValueInfoService;
import cn.gdut.chengcai.service.MemberInfoService;
import cn.gdut.chengcai.service.SecretKeyInfoService;
import cn.gdut.chengcai.service.ValidateLogInfoService;
import cn.gdut.chengcai.vo.MemberInfoVo;

/**
 * 找回密码控制器（不需要登录）
 *
 */
@Controller
@RequestMapping("/retrievePassword")
public class RetrievePasswordController {

	@Autowired
	protected MemberInfoService memberInfoService;

	@Autowired
	protected SecretKeyInfoService secretKeyInfoService;

	@Autowired
	protected EmailTemplateInfoService emailTemplateInfoService;

	@Autowired
	protected EmailLogInfoService emailLogInfoService;

	@Autowired
	protected KeyValueInfoService keyValueInfoService;

	@Autowired
	protected ValidateLogInfoService validateLogInfoService;

	/*@Autowired
	protected MemberInfoService memberInfoService;
	
	@Autowired
	protected SecretKeyInfoService secretKeyInfoService;
	
	@Autowired
	protected EmailTemplateInfoService emailTemplateInfoService;
	
	@Autowired
	protected EmailLogService emailLogService;
	
	@Autowired
	protected KeyValueInfoService keyValueInfoService;
	
	@Autowired
	protected ValidateLogService validateLogService;*/

	/**
	 * 密码找回-成功页
	 */

	@RequestMapping("/success")
	public String success(ModelMap map, HttpServletRequest request, HttpSession session) {
		map.put(ConstantUtil.RESULT_TITLE, "找回密码");
		map.put(ConstantUtil.RESULT_MESSAGE, "找回密码成功！");
		map.put(ConstantUtil.RESULT_RETURN_URI, "/login.html");
		session.setAttribute(ConstantUtil.SESSION_RETRIVE_PASSWORD_STEP, null);
		return "/common/resultSuccess";
	}

	/**
	 * 密码找回-失败页
	 */

	@RequestMapping("/failure")
	public String failure(ModelMap map, HttpServletRequest request, HttpSession session) {
		map.put(ConstantUtil.RESULT_TITLE, "找回密码");
		map.put(ConstantUtil.RESULT_MESSAGE, "找回密码失败。如果遇到问题，请联系管理员！");
		map.put(ConstantUtil.RESULT_RETURN_URI, "/index.html");
		session.setAttribute(ConstantUtil.SESSION_RETRIVE_PASSWORD_STEP, null);
		return "/common/resultFailure";
	}

	/**
	 * 找回密码-邮箱找回-输入账号
	 */
	@RequestMapping("/step1")
	public String step1(HttpSession session) {
		RequestUtil.resetToken(session);
		return "/retrievePassword/step1";
	}

	/**
	 * 找回密码-邮箱找回-发送密钥操作
	 */
	@RequestMapping(value = "/step1Action", method = RequestMethod.POST)
	@ResponseBody
	public ResponseData<Object> step1Action(@RequestBody String jsonString, HttpServletRequest request,
			HttpSession session) {
		ResponseData<Object> result = new ResponseData<>();
		result.setIsSuccess(false);
		MemberInfoVo param = (MemberInfoVo) JsonUtil.fromJson(jsonString, MemberInfoVo.class);

		String ip = RequestUtil.getRemoteHost(request);

		try {

			// 只能重新通过参数中的getEmail()来查找对象，防止param被恶意赋值
			MemberInfoExample example = new MemberInfoExample();
			example.createCriteria().andEmailEqualTo(param.getEmail());
			List<MemberInfo> list = memberInfoService.selectByExample(example);
			if ((list == null) || (list.size() == 0)) {
				result.setMessage(MessageUtil.ACCOUNT_NOT_EXIST_ERROR);
				return result;
			}
			MemberInfo entity = list.get(0);

			// 设置忘记密码确认邮件的密钥，数据库插入该元组
			SecretKeyInfo secretKeyInfo = new SecretKeyInfo();
			secretKeyInfo.setSecretKey(UUID.randomUUID().toString().replace("-", ""));
			secretKeyInfo.setMemberId(entity.getId());

			String[] args = new String[2];
			args[0] = entity.getEmail();
			args[1] = secretKeyInfo.getSecretKey();// uuid设置密钥

			// 发送邮件
			if (EmailUtil.sendSystemMail(emailLogInfoService, emailTemplateInfoService, keyValueInfoService, ip,
					EmailTemplateType.RETRIEVE_PASSOWRD.getValue(), entity.getEmail(), args) == false) {
				return result;
			} else {
				Date date = new Date();
				secretKeyInfo.setCreateTime(date);
				Calendar ca = Calendar.getInstance();
				ca.setTime(date);
				ca.add(Calendar.HOUR_OF_DAY, 2);// 2小时内有效
				secretKeyInfo.setOutDate(ca.getTime());
				secretKeyInfo.setStatus(true);
				secretKeyInfo.setIsDeleted(false);
				secretKeyInfo.setCreateTime(date);
				secretKeyInfoService.insert(secretKeyInfo);
				result.setIsSuccess(true);
			}
		} catch (Exception e) {
			result.setMessage(MessageUtil.SYSTEM_ERROR);
		} finally {
			ValidateLogInfo validateLog = new ValidateLogInfo();
			validateLog.setName(param.getEmail());
			validateLog.setIp(ip);
			validateLog.setDescription(result.getMessage());
			validateLog.setIsAdmin(false);
			validateLog.setIsSuccessed(result.getIsSuccess());
			validateLog.setDescription(result.getMessage());
			validateLog.setIsDeleted(false);
			validateLog.setCreateTime(new Date());
			validateLogInfoService.insert(validateLog);
		}
		return result;
	}

	/**
	 * 找回密码-发送邮件成功页
	 */
	@RequestMapping("/step1Success")
	public String step1Success(ModelMap map, HttpServletRequest request, HttpSession session) {
		map.put(ConstantUtil.RESULT_TITLE, "找回密码");
		map.put(ConstantUtil.RESULT_MESSAGE, "邮件发送成功，请登录邮箱查阅邮件。如果遇到问题，请联系管理员！");
		map.put(ConstantUtil.RESULT_RETURN_URI, "/index.html");
		return "/retrievePassword/step1Success";
	}
	
	/**
	 * 找回密码-发送邮件失败页
	 */

	@RequestMapping("/step1Failure")
	public String step1Failure(ModelMap map, HttpServletRequest request, HttpSession session) {
		map.put(ConstantUtil.RESULT_TITLE, "找回密码");
		map.put(ConstantUtil.RESULT_MESSAGE, "邮件发送失败。如果遇到问题，请联系管理员！");
		map.put(ConstantUtil.RESULT_RETURN_URI, "/retrievePassword/step1.html");
		return "/retrievePassword/step1Failure";
	}

	/**
	 * 找回密码-邮箱找回-确认密钥页
	 */

	@RequestMapping("/confirm")
	public String step2(HttpServletRequest request, ModelMap map) {

		String secretKey = RequestUtil.getParameter(request, "uuid");
		SecretKeyInfoExample example = new SecretKeyInfoExample();
		example.createCriteria().andSecretKeyEqualTo(secretKey).andIsDeletedEqualTo(false);
		List<SecretKeyInfo> list = secretKeyInfoService.selectByExample(example);
		if (list != null && list.size() > 0) {
			SecretKeyInfo entity = list.get(0);
			if (entity.getOutDate().before(new Date()) || !entity.getStatus()) {

			} else {
				MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(entity.getMemberId());
				MemberInfoVo memberInfoVo = new MemberInfoVo();
				try {
					MemberUtil.fillVo(memberInfo, memberInfoVo);
				} catch (Exception e) {
					return "/common/resultFailure";
				}
				map.put("entity", memberInfoVo);
				map.put("secretKey", secretKey);
				return "/retrievePassword/step2";
			}
		}
		// 失败情况的处理
		map.put(ConstantUtil.RESULT_TITLE, "找回密码");
		map.put(ConstantUtil.RESULT_MESSAGE, MessageUtil.SECRECT_KEY_INVALID);
		map.put(ConstantUtil.RESULT_RETURN_URI, "/index.html");
		return "/common/resultFailure";
	}

	/**
	 * 找回密码-邮箱找回-密码重置操作
	 */

	@RequestMapping(value = "/step2Action", method = RequestMethod.POST)
	@ResponseBody
	public ResponseData<Object> step2Action(@RequestBody String jsonString, HttpServletRequest request,
			HttpSession session) {
		ResponseData<Object> result = new ResponseData<>();
		result.setIsSuccess(false);
		try {

			MemberInfoVo param = (MemberInfoVo) JsonUtil.fromJson(jsonString, MemberInfoVo.class);
			SecretKeyInfoExample example = new SecretKeyInfoExample();
			example.createCriteria().andSecretKeyEqualTo(param.getSecretKey()).andIsDeletedEqualTo(false);
			List<SecretKeyInfo> list = secretKeyInfoService.selectByExample(example);
			if (list != null && list.size() > 0) {
				SecretKeyInfo entity = list.get(0);
				if (entity.getOutDate().before(new Date()) || !entity.getStatus()) {
					result.setMessage(MessageUtil.SECRECT_KEY_INVALID);
					return result;
				}
				entity.setStatus(false);
				entity.setClickTime(new Date());
				entity.setIp(RequestUtil.getRemoteHost(request));
				secretKeyInfoService.updateByPrimaryKey(entity);

				MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(param.getId());
				memberInfo.setPassword(param.getPassword());
				memberInfoService.updateByPrimaryKey(memberInfo);
				result.setIsSuccess(true);
			}
		} catch (Exception e) {
			result.setMessage(MessageUtil.SYSTEM_ERROR);
		}
		return result;
	}

	

}